home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / bash_114.zip / bash-1.14.2 / bracecomp.c < prev    next >
C/C++ Source or Header  |  1994-08-03  |  4KB  |  167 lines

  1. /* bracecomp.c -- Complete a filename with the possible completions enclosed
  2.    in csh-style braces such that the list of completions is available to the
  3.    shell. */
  4.  
  5. /* Original version by tromey@cns.caltech.edu,  Fri Feb  7 1992. */
  6.  
  7. /* Copyright (C) 1993 Free Software Foundation, Inc.
  8.  
  9.    This file is part of GNU Bash, the Bourne Again SHell.
  10.  
  11.    Bash is free software; you can redistribute it and/or modify it under
  12.    the terms of the GNU General Public License as published by the Free
  13.    Software Foundation; either version 2, or (at your option) any later
  14.    version.
  15.  
  16.    Bash is distributed in the hope that it will be useful, but WITHOUT ANY
  17.    WARRANTY; without even the implied warranty of MERCHANTABILITY or
  18.    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  19.    for more details.
  20.  
  21.    You should have received a copy of the GNU General Public License along
  22.    with Bash; see the file COPYING.  If not, write to the Free Software
  23.    Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
  24.  
  25. #include <stdio.h>
  26.  
  27. #if defined (HAVE_STRING_H)
  28. #  include <string.h>
  29. #else /* !HAVE_STRING_H */
  30. #  include <strings.h>
  31. #endif /* !HAVE_STRING_H */
  32.  
  33. #include "shell.h"
  34. #include <readline/readline.h>
  35.  
  36. /* Find greatest common prefix of two strings. */
  37. static int
  38. string_gcd (s1, s2)
  39.      char *s1, *s2;
  40. {
  41.   register int i;
  42.  
  43.   if (s1 == NULL || s2 == NULL)
  44.     return (0);
  45.  
  46.   for (i = 0; *s1 && *s2; ++s1, ++s2, ++i)
  47.     {
  48.       if (*s1 != *s2)
  49.     break;
  50.     }
  51.  
  52.   return (i);
  53. }
  54.  
  55. static char *
  56. really_munge_braces (array, real_start, real_end, gcd_zero)
  57.      char **array;
  58.      int real_start, real_end, gcd_zero;
  59. {
  60.   int start, end, gcd;
  61.   char *result, *subterm;
  62.   int result_size, flag;
  63.  
  64.   flag = 0;
  65.  
  66.   if (real_start == real_end)
  67.     {
  68.       if (array[real_start])
  69.         return (savestring (array[real_start] + gcd_zero));
  70.       else
  71.         return (savestring (array[0]));
  72.     }
  73.  
  74.   result = (char *) xmalloc (result_size = 1);
  75.   *result = '\0';
  76.  
  77.   for (start = real_start; start < real_end; start = end + 1)
  78.     {
  79.       gcd = strlen (array[start]);
  80.       for (end = start + 1; end < real_end; end++)
  81.     {
  82.       int temp;
  83.  
  84.       temp = string_gcd (array[start], array[end]);
  85.  
  86.       if (temp <= gcd_zero)
  87.         break;
  88.  
  89.       gcd = temp;
  90.     }
  91.       end--;
  92.  
  93.       if (gcd_zero == 0 && start == real_start && end != (real_end - 1))
  94.     {
  95.       /* In this case, add in a leading '{', because we are at
  96.          top level, and there isn't a consistent prefix. */
  97.       result_size += 1;
  98.       result = (char *) xrealloc (result, result_size);
  99.       strcpy (result, "{");
  100.       flag++;
  101.     }
  102.  
  103.       if (start == end)
  104.     subterm = savestring (array[start] + gcd_zero);
  105.       else
  106.     {
  107.       /* If there is more than one element in the subarray,
  108.          insert the prefix and an opening brace. */
  109.       result_size += gcd - gcd_zero + 1;
  110.       result = (char *) xrealloc (result, result_size);
  111.       strncat (result, array[start] + gcd_zero, gcd - gcd_zero);
  112.       strcat (result, "{");
  113.       subterm = really_munge_braces (array, start, end + 1, gcd);
  114.       subterm[strlen (subterm) - 1] = '}';
  115.     }
  116.  
  117.       result_size += strlen (subterm) + 1;
  118.       result = (char *) xrealloc (result, result_size);
  119.       strcat (result, subterm);
  120.       strcat (result, ",");
  121.       free (subterm);
  122.     }
  123.  
  124.   if (gcd_zero == 0)
  125.     result[strlen (result) - 1] = flag ? '}' : '\0';
  126.   return (result);
  127. }
  128.  
  129. static void
  130. hack_braces_completion (names)
  131.      char **names;
  132. {
  133.   register int i;
  134.   char *temp;
  135.  
  136.   temp = really_munge_braces (names, 1, array_len (names), 0);
  137.  
  138.   for (i = 0; names[i]; ++i)
  139.     {
  140.       free (names[i]);
  141.       names[i] = NULL;
  142.     }
  143.   names[0] = temp;
  144. }
  145.  
  146. void
  147. bash_brace_completion ()
  148. {
  149.   Function *orig_ignore_func;
  150.   Function *orig_entry_func;
  151.   CPPFunction *orig_attempt_func;
  152.  
  153.   orig_ignore_func = rl_ignore_some_completions_function;
  154.   orig_attempt_func = rl_attempted_completion_function;
  155.   orig_entry_func = rl_completion_entry_function;
  156.  
  157.   rl_completion_entry_function = (Function *) filename_completion_function;
  158.   rl_attempted_completion_function = NULL;
  159.   rl_ignore_some_completions_function = (Function *) hack_braces_completion;
  160.  
  161.   rl_complete_internal (TAB);
  162.  
  163.   rl_ignore_some_completions_function = orig_ignore_func;
  164.   rl_attempted_completion_function = orig_attempt_func;
  165.   rl_completion_entry_function = orig_entry_func;
  166. }
  167.